package com.sfchen.cloud.config;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class ObjectMapperConfig {

  private static final DateTimeFormatter LOCAL_DATA_TIME_FORMATTER = DateTimeFormatter.ofPattern(
      "yyyy-MM-dd HH:mm:ss");
  private static final DateTimeFormatter LOCAL_TIME_FORMATTER = DateTimeFormatter.ofPattern(
      "HH:mm:ss");

  @Bean
  @Primary
  public ObjectMapper objectMapper() {

    return getObjectMapper();
  }


   public  static ObjectMapper getObjectMapperByDefault() {
    return getObjectMapper();
  }

  static ObjectMapper getObjectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE);
    builder.deserializerByType(LocalDateTime.class,
        new LocalDateTimeDeserializer(ObjectMapperConfig.LOCAL_DATA_TIME_FORMATTER));
    builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(ObjectMapperConfig.LOCAL_TIME_FORMATTER));
    builder.serializerByType(LocalDateTime.class,
        new LocalDateTimeSerializer(ObjectMapperConfig.LOCAL_DATA_TIME_FORMATTER));
    builder.serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE);
    builder.serializerByType(LocalTime.class, new LocalTimeSerializer(ObjectMapperConfig.LOCAL_TIME_FORMATTER));
    builder.serializationInclusion(Include.ALWAYS);
    builder.featuresToDisable(
        SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
        DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
        DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    builder.featuresToEnable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    builder.featuresToEnable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
    builder.timeZone("GMT+8");
    return builder.build();
  }

}
